﻿#include <iostream>
#include <vector>
#include <string>
using namespace std;

//class Teacher
//{
//public:
//	// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证
//	void identity()
//	{
//		// ...
//	}
//	// 授课
//	void teaching()
//	{
//		//...
//	}
//protected:
//	string _name = "张三"; // 姓名
//	int _age = 18; // 年龄
//	string _address; // 地址
//	string _tel; // 电话
//	string _title; // 职称
//};
//int main()
//{
//	return 0;
//}

//namespace test1_n
//{
//	class Person
//	{
//	public:
//		// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证
//		void identity()
//		{
//			cout << "void identity()" << _name << endl;
//		}
//
//	protected:
//		string _name = "张三"; // 姓名
//		string _address; // 地址
//		string _tel; // 电话
//	private:
//		int _age = 18; // 年龄
//	};
//
//	class Student : Person //默认私有继承
//	{
//	public:
//		// 学习
//		void study()
//		{
//			// ...
//		}
//
//	protected:
//		int _stuid ; // 学号
//	};
//
//	struct Teacher : Person //默认公有继承
//	{
//	public:
//		// 授课
//		void teaching()
//		{
//			// ...
//		}
//	protected:
//		string title; // 职称
//	};
//}
//
//
//void test1()
//{
//	test1_n::Student s;
//	test1_n::Teacher t;
//	//s.identity();
//	//t.identity();
//}


namespace bit
{
	//template<class T>
	//class vector
	//{};
	// stack和vector的关系，既符合is-a，也符合has-a
	template<class T>
	class stack : public std::vector<T>
	{
	public:
		void push(const T& x)
		{
			// 基类是类模板时，需要指定⼀下类域，
			// 否则编译报错:error C3861: “push_back”: 找不到标识符
			// 因为stack<int>实例化时，也实例化vector<int>了
			// 但是模版是按需实例化，push_back等成员函数未实例化，所以找不到
			vector<T>::push_back(x);
			//push_back(x);
		}
		void pop()
		{
			vector<T>::pop_back();
		}
		const T& top()
		{
			return vector<T>::back();
		}
		bool empty()
		{
			return vector<T>::empty();
		}
	};
}

void test2()
{
	bit::stack<int> st;
	st.push(1);
	st.push(2);
	st.push(3);
	while (!st.empty())
	{
		cout << st.top() << " ";
		st.pop();
	}
}




//class Person
//{
////protected:
//public:
//	string _name; // 姓名
//	string _sex; // 性别
//	int _age; // 年龄
//};
//class Student : public Person
//{
//public:
//	int _No; // 学号
//};
//
//void test3()
//{
//	Student sobj;
//
//	Person* pp = &sobj;
//	Person& rp = sobj;
//
//	pp->_name = "张一";
//	rp._name = "张二";
//
//}


//class Person
//{
//protected:
//	string _name = "小李子"; // 姓名
//	int _num = 111; // ⾝份证号
//};
//
//class Student : public Person
//{
//public:
//	void Print()
//	{
//		cout << " 姓名:" << _name << endl;
//		cout << " 身份证号:" << Person::_num << endl;
//		cout << " 学号:" << _num << endl;
//	}
//protected:
//	int _num = 999; // 学号
//};
//
//void test4()
//{
//	Student s1;
//	s1.Print();
//}


class A
{
public:
	void fun()
	{
		cout << "func()" << endl;
	}

	void fun1()
	{
		cout << "fun1()" << endl;
	}
};

class B : public A
{
public:
	void fun(int i)
	{
		cout << "func(int i)" << i << endl;
	}
};

void test5()
{
	B b;
	b.fun(10);
	b.A::fun();
	b.fun1();
}


class Person
{
public:
	Person(const char* name = "xxx")
		:_name(name)
	{
		cout << "Person()" << endl;
	}

	Person(const Person& p)
		:_name(p._name)
	{
		cout << "Person(const Person& p)" << endl;
	}

	Person& operator=(const Person& p)
	{
		cout << "Person& operator=(const Person& p)" << endl;
		if (this != &p)
			_name = p._name;
		return *this;
	}

	~Person()
	{
		cout << "~Person()" << endl;
	}

protected:
	string _name;//姓名
};

class Student : public Person
{
public:
	// 不显示写构造函数，编译器默认生成的构造函数的行为：
	// 1.内置类型->不确定，由编译器决定
	// 2.自定义类型->调用默认构造
	// 3.继承父类成员看作一个整体对象，要求调用父类的默认构造

	//显示写构造函数
	//正确写法
	Student(const char* name = "xxx", int num = 7, const char* address = "翻斗花园")
		:Person(name)
		,_num(num)
		,_address(address)
	{
		cout << "Student()" << endl;
	}

	//错误写法
	//Student(const char* name, int num, const char* address)
	//	:_name(name)
	//	,_num(num)
	//	,_address(address)
	//{
	//	cout << "Student()";
	//}

	Student(const Student& s)
		:Person(s)
		,_num(s._num)
		,_address(s._address)
	{
		//深拷贝
		cout << "Student(const Student& s)" << endl;
	}

	// 严格说Student赋值重载默认生的就够用了
	// 如果有需要深拷贝的资源，才需要自己实现
	Student& operator=(const Student& s)
	{
		if (this != &s)
		{
			Person::operator=(s);
			//operator=(s);
			_num = s._num;
			_address = s._address;
		}

		return *this;
	}

	~Student()
	{
		cout << "~Student()" << endl;
	}


protected:
	int _num;
	string _address;
};

void test6()
{
	Student s1("张三", 18, "翻斗花园");
	//Student s2(s1);
	//Student s3;
	//
	//s3 = s1;


}


int main()
{
	//test1();
	//test3();
	//test4();
	//test5();

	test6();

	return 0;
}
